const fs = require("fs");
const path = require("path");


/**
 * @description // 递归读取文件，类似于webpack的require.context()
 * @time 2020-9-12
 *
 * @param {String} directory 文件目录
 * @param {Boolean} useSubdirectories 是否查询子目录，默认false
 * @param {array} extList 查询文件后缀，默认 ['.js']
 *
 */
const getPathInfo = (p) => path.parse(p);
function autoLoadFile(directory, useSubdirectories = false, extList = [".js"]) {
  const filesList = [];
  // 递归读取文件
  function readFileList(directory, useSubdirectories, extList) {
    const files = fs.readdirSync(directory).filter(item=>item != '.DS_Store');
    files.forEach((item) => {
      const fullPath = path.join(directory, item);
      const stat = fs.statSync(fullPath);
      if (stat.isDirectory() && useSubdirectories) {
        readFileList(path.join(directory, item), useSubdirectories, extList);
      } else {
        const info = getPathInfo(fullPath);
        extList.includes(info.ext) && filesList.push(fullPath);
      }
    });
  }
  readFileList(directory, useSubdirectories, extList);
  // 生成需要的对象
  const res = filesList.map((item) => ({
    path: item,
    data: require(item),
    ...getPathInfo(item),
  }));

  return res;
}

// 日志
const logQueue = [];
let logLock = false;
let WS = null;
const endLog = {}
// 初始化ws
function initWs(ws) {
  WS = ws;
}
// 添加日志
function addLog(data, filename,type = 'log') {
  if (filename != undefined) {
    WS && WS.send(JSON.stringify( { type, data, filename }));
    endLog[filename] = data
  } else {
    WS && WS.send(JSON.stringify({ type , data }));
  }
  logQueue.push({ data, filename ,type});
  saveRun();

}
function getEndLog(filename) {
  return endLog[filename]
}
// 执行日志队列
function saveRun() {
  if (logLock) {
    return;
  }
  if (logQueue.length) {
    logLock = true;
    let task = logQueue.shift();
    saveLog(task)
      .then(() => {
        logLock = false;
        saveRun();
      })
      .catch(() => {
        logLock = false;
        saveRun();
      });
  }
}
// 保存日志
function saveLog({ data, filename=undefined ,type}) {

  if (typeof data != "string") {
    data = JSON.stringify(data);
  }
  let logBasePath = path.resolve(__dirname, "../../log/");
  if (filename) logBasePath = path.resolve(__dirname, "../../log/" + filename);
  // 按时间持续保存
  data = "\r\r" + new Date().toLocaleString() + "----" + data;
  return new Promise((resFn, rejFn) => {
    // time 是年-月-日
    let time = new Date().toLocaleDateString().replace(/\//g, "-");
    let logPath = path.resolve(
      __dirname,
      logBasePath,
      time + ".log"
    );
    // 判断是否存在filename文件夹
    if (filename) {
      let filePath = path.resolve(__dirname, logBasePath);
      if (!fs.existsSync(filePath)) {
        fs.mkdirSync(filePath);
      }
      
    }
    fs.appendFile(logPath, data,  (err)=> {
      if (err) {
        console.log(err);
        rejFn();
      } else {
        resFn();
      }
    });
  });
}
function clearLog() {
  return new Promise((resFn, rejFn) => {
    // 清除log文件里面时间超过7天的日志
    let logPath = path.resolve(__dirname, "../../log/");
    fs.readdir(logPath,  (err, files)=> {
      if (err) {
        console.log(err);
        rejFn();
      } else {
        let time = new Date().getTime();
        files.forEach((item) => {
          // 如果item是文件夹就遍历文件夹里面的文件
          if (fs.statSync(logPath + "/" + item).isDirectory()) {
            let filePath2 = path.resolve(__dirname, "../../log/" + item);
            let files2 = fs.readdirSync(filePath2);
            files2.forEach((item2) => {
              let filePath = path.resolve(__dirname, "../../log/" + item, item2);
              let fileTime = item2.split(".")[0];
              fileTime = new Date(fileTime).getTime();
              if (time - fileTime > 7 * 24 * 60 * 60 * 1000) {
                fs.unlink(filePath, (err)=> {
                  if (err) {
                    console.log(err);
                  } else {
                    console.log(item2 + "删除成功");
                  }
                });
              }
            });
            return;
          }
          let filePath = path.resolve(__dirname, "../../log/", item);
          let fileTime = item.split(".")[0];
          fileTime = new Date(fileTime).getTime();
          if (time - fileTime > 7 * 24 * 60 * 60 * 1000) {
            fs.unlink(filePath,  (err)=> {
              if (err) {
                console.log(err);
              } else {
                console.log(item + "删除成功");
              }
            });
          }
        });
        resFn();
      }
    });
  });
}

function promiseLog(log,cb){
  addLog('开始：'+log.text, log.projectName);
  return new Promise((resolve,reject)=>{
    cb().then(()=>{
      addLog(log.success || (log.text+'成功') , log.projectName);
      resolve();
    }).catch(()=>{
      addLog(log.error || (log.text+'失败'), log.projectName);
      reject();
    })
  })
}

// 目录拷贝 src 源目录 dist 目标目录
function copyDir(src, dist) {
  return new Promise((resolve,reject)=>{

    fs.access(dist, function (err) {
      if (err) {
        // 目录不存在时创建目录
        fs.mkdirSync(dist);
      }
      _copy(null, src, dist);
    });
    function _copy(err, src, dist) {
      if (err) {
        reject(err);
        throw err;
      } else {
        fs.readdir(src, function (err, paths) {
          if (err) {
            reject(err);
            throw err;
          } else {
            paths.forEach(function (path) {
              var _src = src + "/" + path;
              var _dist = dist + "/" + path;
              fs.stat(_src, function (err, stat) {
                if (err) {
                  reject(err);
                  throw err;
                } else {
                  // 判断是文件还是目录
                  if (stat.isFile()) {
                    fs.writeFileSync(_dist, fs.readFileSync(_src));
                  } else if (stat.isDirectory()) {
                    // 当是目录是，递归复制
                    copyDir(_src, _dist);
                  }
                }
              });
            });
          }
        });
      }
    }
    resolve();
  })
}



module.exports = {
  autoLoadFile,
  addLog,
  initWs,
  clearLog,
  getEndLog,
  promiseLog,
  copyDir
};
